package com.zlyx.easy.web.jpa.controller;

import java.lang.reflect.Field;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.zlyx.easy.core.exception.BusinessException;
import com.zlyx.easy.core.utils.JsonUtils;
import com.zlyx.easy.core.utils.RandomUtils;
import com.zlyx.easy.swagger.annotations.SpringMapping;
import com.zlyx.easy.web.jpa.service.JpaService;

/**
 *
 * @param <T>
 * @param <T>
 * @Author 赵光
 * @Desc BaseController
 * @Date 2020年5月10日
 */
public class BaseController<Service extends JpaService<? extends JpaRepository<T, ID>, T, ID>, T, ID> {

	protected Logger logger = LoggerFactory.getLogger(getClass());

	@Autowired
	protected Service baseService;

	/**
	 * 分页查询
	 * 
	 * @param pageNum
	 * @param pageSize
	 * @param entity
	 * @return
	 */
	@SpringMapping(notes = "分页查询", todo = { "分页查询" }, value = { "/page" }, method = RequestMethod.GET)
	public Page<T> page(@RequestParam(name = "pageNum", defaultValue = "0") int current,
			@RequestParam(name = "pageSize", defaultValue = "10") int size, T entity) {
		return doPage(current, size, entity);
	}

	/**
	 * 分页逻辑(请根据需要自己实现)
	 * 
	 * @param current
	 * @param size
	 * @param entity
	 * @return
	 */
	protected Page<T> doPage(int current, int size, T entity) {
		return this.baseService.findAll(entity, current, size);
	}

	/**
	 * 条件查询
	 * 
	 * @param entity
	 * @return
	 */
	@SpringMapping(notes = "条件查询", todo = { "条件查询" }, value = { "/list" }, method = RequestMethod.GET)
	public List<T> list(T entity) {
		return this.baseService.findAll(entity);
	}

	/**
	 * 根据id查询
	 * 
	 * @param id
	 * @return
	 */
	@SpringMapping(notes = "根据id查询", todo = { "根据id查询" }, value = { "/get/{id}" }, method = RequestMethod.GET)
	public T getById(@PathVariable(name = "id") ID id) {
		return this.baseService.getById(id);
	}

	/**
	 * 新增记录
	 * 
	 * @param entity
	 * @return
	 * @throws Exception
	 */
	@SpringMapping(notes = "新增", todo = { "新增" }, value = { "/save" }, method = RequestMethod.POST)
	public T save(@Validated T entity) throws Exception {
		if (Boolean.FALSE == doBeforeSave(entity)) {
			BusinessException.throwAndLogException("实体对象验证失败");
		}
		return this.baseService.save(entity);
	}

	/**
	 * 批量新增
	 * 
	 * @param entityList
	 * @return
	 * @throws Exception
	 */
	@SpringMapping(notes = "批量新增", todo = { "批量新增" }, value = { "/save-batch" }, method = RequestMethod.POST)
	public List<T> saveBatch(@RequestBody List<T> entityList) throws Exception {
		if (entityList == null || entityList.isEmpty()) {
			BusinessException.throwException("实体对象列表为空");
		}
		for (T entity : entityList) {
			// 如果返回失败，那么结束操作
			if (Boolean.FALSE == doBeforeSave(entity)) {
				BusinessException.throwAndLogException("实体对象验证失败");
			}
		}
		return this.baseService.saveAll(entityList);
	}

	/**
	 * 保存对象前自定义定制化操作
	 * 
	 * @param entity
	 * @throws Exception
	 */
	public boolean doBeforeSave(T entity) throws Exception {
		Field field = entity.getClass().getDeclaredField("id");
		field.setAccessible(true);
		if (field != null) {
			Object value = field.get(entity);
			if (value == null || "".equals(value)) {
				Class<?> fieldType = field.getType();
				if (String.class == fieldType) {
					field.set(entity, RandomUtils.randomUUID());
				} else {
					field.set(entity, RandomUtils.randomNum());
				}
			}
		}
		return true;
	}

	/**
	 * 根据id批量更新
	 * 
	 * @param entity
	 * @return
	 * @throws Exception
	 */
	@SpringMapping(notes = "根据id批量更新", todo = { "根据id批量更新" }, value = { "/update" }, method = RequestMethod.PUT)
	public T updateById(T entity) throws Exception {
		if (Boolean.FALSE == doBeforeSave(entity)) {
			BusinessException.throwAndLogException("实体对象验证失败");
		}
		return this.baseService.save(entity);
	}

	/**
	 * 批量更新
	 * 
	 * @param entityList
	 * @return
	 * @throws Exception
	 */
	@SpringMapping(notes = "批量更新", todo = { "批量更新" }, value = { "/update-batch" }, method = RequestMethod.PUT)
	public List<T> updateBatch(@RequestBody List<T> entityList) throws Exception {
		if (entityList == null || entityList.isEmpty()) {
			BusinessException.throwException("实体对象列表为空");
		}
		for (T entity : entityList) {
			// 如果返回失败，那么结束操作
			if (Boolean.FALSE == doBeforeSave(entity)) {
				BusinessException.throwAndLogException("实体对象验证失败");
			}
		}
		return this.baseService.saveAll(entityList);
	}

	/**
	 * 根据id删除
	 * 
	 * @param id
	 * @return
	 */
	@SpringMapping(notes = "根据id删除", todo = { "根据id删除" }, value = { "/delete/{id}" }, method = RequestMethod.DELETE)
	public void deleteById(@PathVariable("id") ID id) {
		this.baseService.deleteById(id);
	}

	/**
	 * 批量删除(id数组)
	 * 
	 * @param idList
	 * @return
	 * @throws Exception
	 */
	@SpringMapping(notes = "批量删除", todo = { "批量删除" }, value = { "/delete-batch" }, method = RequestMethod.DELETE)
	public boolean deleteByIds(@RequestBody String ids) throws Exception {
		return this.baseService.deleteByIds(JsonUtils.toList(ids));
	}

}
